package org.nobject.common.lang;

import static org.nobject.common.lang.ClassUtils.isMap;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.nobject.common.bean.BeanUtils;
import org.nobject.common.exception.ConvertException;
import org.nobject.common.js.JSONUtils;
/**
 * Map工具类
 *
 * @author bianrongjun
 * @version 1.0
 */
public class MapUtils {
	/** 
	 * 反转KeyValue
	 * @param map Map
	 */
	public static Map reverseKeyValue(Map map){
		try {
			Map m=(Map)map.getClass().newInstance();
			for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
				Object key = iterator.next();
				Object value = map.get(key);
				m.put(value, key);
			}
			return m;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/******************************************************************************************************************
	 * 
	 *  toMap 区域
	 * 
	 *******************************************************************************************************************/
	
	/** 
	 * 2维数组转换为 Map
	 * @param array 2维数组
	 */
	public static Map toMapByArray(Object array){
		Map m=new LinkedHashMap();
		int l=Array.getLength(array);
		for (int i = 0; i < l; i++) {
			Object o=Array.get(array, i);
			m.put(Array.get(o, 0), Array.get(o, 1));
		}
		return m;
	}
	
	/** 
	 * 2维数组转Map
	 * @param os 2维数组
	 */
	public static Map toMap(Object[][] os){
		return toMapByArray(os);
	}
	
	/**
	 * 字符串转化转化为Map,使用JSON格式的解析
	 * @param str 字符串
	 * @throws ConvertException 转换时异常
	 */
	public static Map toMap(String str) throws ConvertException{
		try {
			return JSONUtils.toMap(str);
		} catch (Exception e) {
			throw new ConvertException(e);
		}
	}
	
	/** 
	 * Object到Map的转换<br>
	 * 支持二维数组、JSON格式字符串、及其它Bean类型数据的转换
	 * @param o 对象
	 * @throws ConvertException 转换时异常
	 */
	
	public static Map toMap0(Object obj) throws ConvertException{
		if(obj==null) return null;
		Class c=obj.getClass();
		if(isMap(c)) return (Map)obj;
		Method toMethod=null;
		if(c.isArray())						{return toMapByArray(obj);}
		else if(ClassUtils.isString(c))		{return toMap((String)obj);}
		else if((toMethod=ClassUtils.getToMethod(obj.getClass(), Map.class))!=null){
			try {
				return (Map)toMethod.invoke(obj);
			} catch (Exception e) {
				throw new ConvertException(e);
			}
		}else{
			Field[] fields=ClassUtils.getFields(c);
			Map m=new HashMap();
			for (Field field:fields) {
				String propName = field.getName();
				try {
					Method method = (Method) BeanUtils.getGetMethod(obj.getClass(), propName);
					if(method==null) continue;
					m.put(propName, method.invoke(obj));
				} catch (Exception e) {
					throw new ConvertException(e);
				}
			}
			return m;
		}
	}
	
	/** 
	 * 复制m2到m1
	 * @param dest 目的Map
	 * @param source 复制源Map 
	 * @param override 是否覆盖
	 */
	public static Map copy(Map dest,Map source,boolean override){
		for(Object k:source.keySet()){
			if(!override&&dest.containsKey(k)) continue;
			dest.put(k, source.get(k));
		}
		return dest;
	}
	
	/** 
	 * 转换成2元数组
	 * @param m
	 */
	public static Object[][] toArrays(Map m){
		Object[] [] os=new Object[m.keySet().size()][2];
		
		int i=0;
		for(Object key:m.keySet()){
			os[i][0]=key;
			os[i][1]=m.get(key);
			i++;
		}
		return os;
	}
	
	public static void main(String[] args) {
		Map m=new HashMap();
		m.put("a",1);
		m.put("b",2);
		
		System.out.println(toArrays(m).length);
		
		
	}
	
	/** 
	 * isEmpty
	 * @param m
	 */
	public static boolean isEmpty(Map m){
		return m==null||m.keySet().size()==0;
	}
}
